package cn.iocoder.yudao.module.iot.gateway.protocol.custom.xiaoan.tcp.router.handler;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.iot.core.biz.IotDeviceCommonApi;
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO;
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceRespDTO;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceAuthUtils;
import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.manager.IotTcpConnectionManager;
import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.router.handler.BaseProtocolHandler;
import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.router.handler.ProtocolHandler;
import cn.iocoder.yudao.module.iot.gateway.service.device.IotDeviceService;
import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;

import static cn.iocoder.yudao.module.iot.gateway.protocol.tcp.router.IotTcpUpstreamHandler.AUTH_METHOD;

@Slf4j
@Component
public class XiaoAnAuthProtocolHandler extends XiaoAnBaseProtocolHandler {
    @Resource
    private IotDeviceMessageService deviceMessageService;
    @Resource
    private IotDeviceService deviceService;
    @Resource
    private IotTcpConnectionManager connectionManager;
    @Resource
    private IotDeviceCommonApi deviceApi;

    @Override
    public void handle(String clientId, IotDeviceMessage message, String codecType, NetSocket socket, String serviceId) {
        this.handleAuthenticationRequest(clientId, message, codecType, socket, serviceId);
    }

    @Override
    public String getHandlerType() {
        return "auth";
    }

    @Override
    public String getProtocolType() {
        return "xiaoan";
    }


    /**
     * 处理认证请求
     *
     * @param clientId  客户端 ID
     * @param message   消息信息
     * @param codecType 消息编解码类型
     * @param socket    网络连接
     */
    private void handleAuthenticationRequest(String clientId, IotDeviceMessage message, String codecType,
                                             NetSocket socket, String serverId) {
        try {
//            // 1.1 解析认证参数
//            IotDeviceAuthReqDTO authParams = parseAuthParams(message.getParams());
//            if (authParams == null) {
//                log.warn("[handleAuthenticationRequest][认证参数解析失败，客户端 ID: {}]", clientId);
//                sendErrorResponse(socket, message.getRequestId(), "认证参数不完整", codecType);
//                return;
//            }
//            // 1.2 执行认证
//            if (!validateDeviceAuth(authParams)) {
//                log.warn("[handleAuthenticationRequest][认证失败，客户端 ID: {}，username: {}]",
//                        clientId, authParams.getUsername());
//                sendErrorResponse(socket, message.getRequestId(), "认证失败", codecType);
//                return;
//            }
//            // 2.1 解析设备信息
//            IotDeviceAuthUtils.DeviceInfo deviceInfo = IotDeviceAuthUtils.parseUsername(authParams.getUsername());
//            if (deviceInfo == null) {
//                sendErrorResponse(socket, message.getRequestId(), "解析设备信息失败", codecType);
//                return;
//            }
//            // 2.2 获取设备信息
//            IotDeviceRespDTO device = deviceService.getDeviceFromCache(deviceInfo.getProductKey(),
//                    deviceInfo.getDeviceName());
//            if (device == null) {
//                sendErrorResponse(socket, message.getRequestId(), "设备不存在", codecType);
//                return;
//            }
            IotDeviceRespDTO device = new IotDeviceRespDTO();
            device.setId(1L);
            device.setProductKey("bike");
            device.setDeviceName(getImei(message.getParams()));
            // 3.1 注册连接
            registerConnection(connectionManager, socket, device, clientId, codecType);
            // 响应设备
            sendResponse(deviceMessageService,socket, message.getMethod(), message.getRequestId(), message.getData(), codecType);

            log.info("[handleAuthenticationRequest][认证成功，设备 ID: {}，设备名: {}]",
                    device.getId(), device.getDeviceName());
        } catch (Exception e) {
            log.error("[handleAuthenticationRequest][认证处理异常，客户端 ID: {}]", clientId, e);
            sendErrorResponse(deviceMessageService,socket, message.getRequestId(), "认证处理异常", codecType);
        }

    }

    private String getImei(Object params) {
        if (params == null) {
            return null;
        }
        if (params instanceof java.util.Map) {
            java.util.Map<String, Object> paramMap = (java.util.Map<String, Object>) params;
            return MapUtil.getStr(paramMap, "imei");
        }
        return null;
    }


    /**
     * 解析认证参数
     *
     * @param params 参数对象（通常为 Map 类型）
     * @return 认证参数 DTO，解析失败时返回 null
     */
    @SuppressWarnings("unchecked")
    private IotDeviceAuthReqDTO parseAuthParams(Object params) {
        if (params == null) {
            return null;
        }

        try {
            // 参数默认为 Map 类型，直接转换
            if (params instanceof java.util.Map) {
                java.util.Map<String, Object> paramMap = (java.util.Map<String, Object>) params;
                return new IotDeviceAuthReqDTO()
                        .setClientId(MapUtil.getStr(paramMap, "clientId"))
                        .setUsername(MapUtil.getStr(paramMap, "username"))
                        .setPassword(MapUtil.getStr(paramMap, "password"));
            }

            // 如果已经是目标类型，直接返回
            if (params instanceof IotDeviceAuthReqDTO) {
                return (IotDeviceAuthReqDTO) params;
            }

            // 其他情况尝试 JSON 转换
            String jsonStr = JsonUtils.toJsonString(params);
            return JsonUtils.parseObject(jsonStr, IotDeviceAuthReqDTO.class);
        } catch (Exception e) {
            log.error("[parseAuthParams][解析认证参数({})失败]", params, e);
            return null;
        }
    }

    /**
     * 验证设备认证信息
     *
     * @param authParams 认证参数
     * @return 是否认证成功
     */
    private boolean validateDeviceAuth(IotDeviceAuthReqDTO authParams) {
        try {
            CommonResult<Boolean> result = deviceApi.authDevice(new IotDeviceAuthReqDTO()
                    .setClientId(authParams.getClientId()).setUsername(authParams.getUsername())
                    .setPassword(authParams.getPassword()));
            result.checkError();
            return BooleanUtil.isTrue(result.getData());
        } catch (Exception e) {
            log.error("[validateDeviceAuth][设备认证异常，username: {}]", authParams.getUsername(), e);
            return false;
        }
    }
}
